package com.biz.primus.ms.evaluation.service.impl;

import com.biz.primus.base.exception.BizSilentException;
import com.biz.primus.base.exception.utils.AssertUtils;
import com.biz.primus.model.evaluation.exception.EvaluationException;
import com.biz.primus.model.evaluation.vo.DeliveryEvaluationVO;
import com.biz.primus.model.evaluation.vo.OrderEvaluationVO;
import com.biz.primus.model.evaluation.vo.ProductEvaluationVO;
import com.biz.primus.model.order.enums.CommentState;
import com.biz.primus.model.order.enums.DeliveryState;
import com.biz.primus.model.order.enums.OrderState;
import com.biz.primus.model.order.exception.OrderException;
import com.biz.primus.model.order.exception.utils.AssertRequestParameter;
import com.biz.primus.model.order.vo.response.OrderResponseVO;
import com.biz.primus.ms.evaluation.convertor.DeliveryEvaluationConvertor;
import com.biz.primus.ms.evaluation.convertor.EvaluationConvertor;
import com.biz.primus.ms.evaluation.convertor.ProductEvaluationConvertor;
import com.biz.primus.ms.evaluation.dao.po.DeliveryEvaluation;
import com.biz.primus.ms.evaluation.dao.po.OrderEvaluation;
import com.biz.primus.ms.evaluation.dao.po.ProductEvaluation;
import com.biz.primus.ms.evaluation.service.EvaluationService;
import com.biz.primus.ms.evaluation.service.helper.EvaluationServiceHelper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.Transient;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单服务实现
 *
 * @author Tiger Feng
 * @date 2017年10月30日
 */
@Slf4j
@Service
public class EvaluationServiceImpl implements EvaluationService {
    @Autowired
    private EvaluationServiceHelper helper;

    /*@Transactional(rollbackFor = Exception.class)
    @Override
    public OrderEvaluationVO evaluateOrder(OrderEvaluationVO vo) {
        AssertUtils.hasLength(vo.getOrderCode(), OrderException.ORDER_CODE_CANNOT_NULL);
        // 调用订单接口:检查订单当前状态是否允许评价
        OrderResponseVO orderVO = helper.getOrderVOByOrderCode(vo.getOrderCode());
        AssertUtils.notNull(orderVO, OrderException.ORDER_NOT_EXIST);
        // 校验支付状态是否满足评价
        switch (orderVO.getPaymentState()) {
            case WAIT_PAY:
                // 等待支付
                throw new BizSilentException(OrderException.PLEASE_PAY);
            case PAY_FAILURE:
                // 支付失败
                throw new BizSilentException(OrderException.PLEASE_PAY);
            default:
                break;
        }
        // 校验物流状态是否满足评价,非 已收货和部分收货，拒绝评价
        DeliveryState deliveryState = orderVO.getDelivery().getDeliveryState();
        if (deliveryState != DeliveryState.SIGNED && deliveryState != DeliveryState.PART_OF_SIGNED) {
            throw new BizSilentException(OrderException.CANNOT_EVALUATION);
        }
        // 订单状态
        if (OrderState.FINISHED == orderVO.getState()) {
            throw new BizSilentException(OrderException.CANNOT_EVALUATION);
        }
        // 订单评价状态
        if (CommentState.ALREADY_COMMENTS == orderVO.getCommentState()) {
            throw new BizSilentException(OrderException.CANNOT_EVALUATION);
        }
        // 评价订单
        OrderEvaluation po = EvaluationConvertor.vo2PO(vo);
        // 调用订单接口:更新订单评价状态为"已评价"
        vo = EvaluationConvertor.po2VO(helper.save(po));
        // 调用订单接口更新订单状态为已经评价
        helper.evaluateOrderState(vo.getOrderCode());
        return vo;
    }*/

    @Override
    public OrderEvaluationVO getOrderEvaluationVO(String orderCode) {
        AssertUtils.hasLength(orderCode, OrderException.ORDER_CODE_CANNOT_NULL);
        // 直接查询订单号对应的订单评价
        return EvaluationConvertor.po2VO(helper.getOrderEvaluationByOrderCode(orderCode));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public OrderEvaluationVO evaluateCourier(DeliveryEvaluationVO vo) {
        AssertRequestParameter.notNull(vo, "物流评价参数不能为空");
        AssertRequestParameter.hasText(vo.getOrderCode(), "订单编号不能为空");
        OrderResponseVO orderResponseVO = checkOrderEvaluateable(vo.getOrderCode());
        AssertRequestParameter.notNull(orderResponseVO.getDelivery(), "物流信息没有找到");
        AssertRequestParameter.hasText(orderResponseVO.getDelivery().getShipManCode(), "本订单无配送员");
        // 校验物流状态是否满足评价,非 已收货和部分收货，拒绝评价
        DeliveryState deliveryState = orderResponseVO.getDelivery().getDeliveryState();
        if (deliveryState != DeliveryState.SIGNED && deliveryState != DeliveryState.PART_OF_SIGNED) {
            throw new BizSilentException(OrderException.CANNOT_EVALUATION);
        }
        // 评价订单
        OrderEvaluation orderEvaluation = new OrderEvaluation();
        orderEvaluation.setOrderCode(vo.getOrderCode());
        DeliveryEvaluation deliveryEvaluation = DeliveryEvaluationConvertor.vo2PO(vo);
        deliveryEvaluation.setOrderEvaluation(orderEvaluation);
        deliveryEvaluation.setDepotCode(orderResponseVO.getDepotCode());
        deliveryEvaluation.setShipManCode(orderResponseVO.getDelivery().getShipManCode());
        orderEvaluation.setDeliveryEvaluation(deliveryEvaluation);
        // 保存订单评价
        orderEvaluation = helper.saveOrderEvaluation(orderEvaluation);
//        if (orderEvaluation != null) {
//            // 调用订单接口更新订单状态为已经评价
//            helper.evaluateOrderState(vo.getOrderCode());
//        }
        return EvaluationConvertor.po2VO(orderEvaluation);
    }

    @Override
    public OrderEvaluationVO evaluateProduct(ProductEvaluationVO vo) {
        AssertRequestParameter.notNull(vo, "物流评价参数不能为空");
        AssertRequestParameter.hasText(vo.getOrderCode(), "订单编号不能为空");
        AssertRequestParameter.hasText(vo.getProductCode(), "商品编号不能为空");
        AssertRequestParameter.notNull(vo.getScore(), "评分不能为空");
        OrderResponseVO orderResponseVO = checkOrderEvaluateable(vo.getOrderCode());
        AssertRequestParameter.notNull(orderResponseVO.getDelivery(), "物流信息没有找到");
        OrderEvaluation orderEvaluation = helper.getOrderEvaluationByOrderCode(vo.getOrderCode());
        if (orderEvaluation == null) {
            orderEvaluation = new OrderEvaluation();
            orderEvaluation.setOrderCode(orderResponseVO.getOrderCode());
        }
        List<ProductEvaluation> productEvaluations = orderEvaluation.getProductEvaluations();
        if (productEvaluations != null || productEvaluations.isEmpty()) {
            if (productEvaluations.stream().filter(productEvaluation -> vo.getProductCode().equals(productEvaluation.getProductCode())).collect(Collectors.toList()).size() > 0) {
                // 商品已经评论了，禁止修改评论
                throw new BizSilentException(OrderException.CANNOT_EVALUATION);
            }
        } else {
            productEvaluations = Lists.newArrayList();
        }
        ProductEvaluation productEvaluation = ProductEvaluationConvertor.vo2PO(vo);
        productEvaluation.setDepotCode(orderResponseVO.getDepotCode());
        productEvaluation.setOrderEvaluation(orderEvaluation);

        // 保存订单评价
        orderEvaluation = helper.saveOrderEvaluation(orderEvaluation);
        // 当物流和商品都评价完时，通知订单将评价状态更改成已评价
        if (orderEvaluation.getProductEvaluations().size() == orderResponseVO.getItems().size()
                && orderEvaluation.getDeliveryEvaluation() != null) {
            // 调用订单接口更新订单状态为已经评价
            helper.evaluateOrderState(vo.getOrderCode());
        }
        return EvaluationConvertor.po2VO(orderEvaluation);
    }

    private OrderResponseVO checkOrderEvaluateable(String orderCode) {
        // 调用订单接口:检查订单当前状态是否允许评价
        OrderResponseVO orderVO = helper.getOrderVOByOrderCode(orderCode);
        AssertUtils.notNull(orderVO, OrderException.ORDER_NOT_EXIST);
        // 校验支付状态是否满足评价
        switch (orderVO.getPaymentState()) {
            case WAIT_PAY:
                // 等待支付
                throw new BizSilentException(OrderException.PLEASE_PAY);
            case PAY_FAILURE:
                // 支付失败
                throw new BizSilentException(OrderException.PLEASE_PAY);
            default:
                break;
        }
        // 订单状态
        if (OrderState.FINISHED == orderVO.getState()) {
            throw new BizSilentException(OrderException.CANNOT_EVALUATION);
        }
        // 订单评价状态
        if (CommentState.ALREADY_COMMENTS == orderVO.getCommentState()) {
            throw new BizSilentException(OrderException.CANNOT_EVALUATION);
        }
        return orderVO;
    }

}
